#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

mod response;

use response::resp_data::{ResData, ResData2};

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![
            get_local_notebooks,
            remove_temp_note,
            get_note_list,
            read_note_file,
            create_notebook,
            create_note_file,
            save_note,
            remove_notebook,
            remove_note,
            // create_cloud_notebook,
            // save_cloud_note,
            // delete_cloud_note
        ])
        .run(tauri::generate_context!())
        .expect("tauri程序运行失败");
}

// 获取本地笔记本列表
#[tauri::command]
async fn get_local_notebooks(app_handle: tauri::AppHandle) -> Result<ResData<Vec<String>>, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // println!("{:?}", local_data_dir);
        // 文件夹是否存在
        if local_data_dir.exists() {
            let mut notebooks: Vec<String> = vec![];
            let paths = std::fs::read_dir(local_data_dir);
            match paths {
                Ok(ps) => {
                    // 遍历目录
                    for path in ps {
                        let entry = path.unwrap();
                        let path = entry.path();
                        if path.is_dir() {
                            let name = path.file_stem().unwrap();
                            let n = name.to_str().unwrap().to_string();
                            notebooks.push(n);
                        }
                    }
                    return Ok(ResData {
                        code: 200,
                        msg: "success".to_string(),
                        data: notebooks,
                    });
                }
                Err(_) => return Err("读取目录失败".to_string()),
            }
        }
        // 目录不存在则创建
        let a = std::fs::create_dir_all(local_data_dir);
        match a {
            Ok(_) => println!("创建目录成功"),
            Err(_) => return Err("创建目录失败".to_string()),
        }
    }
    Ok(ResData {
        code: 500,
        msg: "读取目录失败".to_string(),
        data: Vec::new(),
    })
}

// 删除本地临时笔记
#[tauri::command]
async fn remove_temp_note(
    app_handle: tauri::AppHandle,
    current_notebook: String,
    current_note: String,
) -> Result<ResData2, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let tem = local_data_dir
                .join(current_notebook)
                .join(current_note + ".md");
            let res = std::fs::remove_file(tem);
            match res {
                Ok(_) => {
                    return Ok(ResData2 {
                        code: 200,
                        msg: "删除成功".to_string(),
                    })
                }
                Err(_) => return Err("删除失败".to_string()),
            }
        }
    }

    Ok(ResData2 {
        code: 500,
        msg: "文件不存在".to_string(),
    })
}

// 获取本地笔记列表
#[tauri::command]
async fn get_note_list(
    app_handle: tauri::AppHandle,
    notebook: String,
) -> Result<ResData<Vec<String>>, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let mut notes: Vec<String> = vec![];

            let paths = std::fs::read_dir(local_data_dir.join(notebook));
            match paths {
                Ok(ps) => {
                    // 遍历文件
                    for path in ps {
                        let entry = path.unwrap();
                        let path = entry.path();
                        if path.is_file() {
                            let name = path.file_stem().unwrap();
                            let n = name.to_str().unwrap().to_string();
                            notes.push(n);
                        }
                    }
                    return Ok(ResData {
                        code: 200,
                        msg: "success".to_string(),
                        data: notes,
                    });
                }
                Err(_) => return Err("读取目录失败".to_string()),
            }
        }
    }
    Ok(ResData {
        code: 500,
        msg: "文件不存在".to_string(),
        data: Vec::new(),
    })
}

// 读取本地笔记文件
#[tauri::command]
async fn read_note_file(
    app_handle: tauri::AppHandle,
    current_notebook: String,
    note_title: String,
) -> Result<ResData<String>, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let file = local_data_dir
                .join(current_notebook)
                .join(note_title + ".md");
            let content = std::fs::read_to_string(file);
            match content {
                Ok(s) => {
                    return Ok(ResData {
                        code: 200,
                        msg: "读取成功".to_string(),
                        data: s,
                    })
                }
                Err(err) => {
                    return Ok(ResData {
                        code: 500,
                        msg: "笔记读取失败".to_string(),
                        data: err.to_string(),
                    })
                }
            }
        }
        return Ok(ResData {
            code: 500,
            msg: "笔记文件不存在".to_string(),
            data: String::new(),
        });
    }
    Ok(ResData {
        code: 500,
        msg: "笔记文件不存在".to_string(),
        data: String::new(),
    })
}

// 创建本地笔记本
#[tauri::command]
async fn create_notebook(
    app_handle: tauri::AppHandle,
    notebook_name: String,
) -> Result<ResData2, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let dir = local_data_dir.join(notebook_name);
            // 创建文件夹
            let res = std::fs::create_dir_all(dir);
            match res {
                Ok(_) => {
                    return Ok(ResData2 {
                        code: 200,
                        msg: "创建成功".to_string(),
                    })
                }
                Err(err) => {
                    return Ok(ResData2 {
                        code: 500,
                        msg: format!("创建失败：{0}", err.to_string()),
                    })
                }
            }
        }
        return Ok(ResData2 {
            code: 500,
            msg: "文件夹不存在".to_string(),
        });
    }
    Ok(ResData2 {
        code: 500,
        msg: "文件夹不存在".to_string(),
    })
}

// 创建笔记
#[tauri::command]
async fn create_note_file(
    app_handle: tauri::AppHandle,
    notebook: String,
) -> Result<ResData<String>, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let name = chrono::prelude::Local::now().timestamp_millis().to_string();
            let temp_file = local_data_dir.join(notebook).join(name.clone() + ".md");
            // println!("{:?}", temp_file);
            // 创建文件夹
            let res = std::fs::File::create(temp_file);
            match res {
                Ok(_) => {
                    return Ok(ResData {
                        code: 200,
                        msg: "创建成功".to_string(),
                        data: name,
                    })
                }
                Err(err) => {
                    return Ok(ResData {
                        code: 500,
                        msg: format!("创建失败：{0}", err.to_string()),
                        data: String::new(),
                    })
                }
            }
        }
        return Ok(ResData {
            code: 500,
            msg: "文件夹不存在".to_string(),
            data: String::new(),
        });
    }
    Ok(ResData {
        code: 500,
        msg: "文件夹不存在".to_string(),
        data: String::new(),
    })
}

// 保存本地笔记
#[tauri::command]
async fn save_note(
    app_handle: tauri::AppHandle,
    current_notebook: String,
    current_note: String,
    md_title: String,
    md_text: String,
) -> Result<ResData2, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let path = local_data_dir
                .join(current_notebook.clone())
                .join(current_note + ".md");
            // println!("原文件名：{:?}", path);
            let new_path = local_data_dir.join(current_notebook).join(md_title + ".md");
            // println!("保存文件名：{:?}", new_path);

            let wres = std::fs::write(path.clone(), md_text);
            match wres {
                Ok(_) => {
                    let new_name_res = std::fs::rename(path, new_path);
                    match new_name_res {
                        Ok(_) => {
                            return Ok(ResData2 {
                                code: 200,
                                msg: "操作成功".to_string(),
                            });
                        }
                        Err(e) => {
                            return Ok(ResData2 {
                                code: 500,
                                msg: e.to_string(),
                            });
                        }
                    }
                }
                Err(e) => {
                    return Ok(ResData2 {
                        code: 500,
                        msg: e.to_string(),
                    });
                }
            }
        }
    }

    Ok(ResData2 {
        code: 500,
        msg: "文件夹不存在".to_string(),
    })
}

// 删除本地笔记本
#[tauri::command]
async fn remove_notebook(
    app_handle: tauri::AppHandle,
    current_notebook: String,
) -> Result<ResData2, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let dir = local_data_dir.join(current_notebook);
            let remove_res = std::fs::remove_dir_all(dir);
            match remove_res {
                Ok(_) => {
                    return Ok(ResData2 {
                        code: 200,
                        msg: "操作成功".to_string(),
                    });
                }
                Err(e) => {
                    return Ok(ResData2 {
                        code: 500,
                        msg: e.to_string(),
                    });
                }
            }
        }
    }
    Ok(ResData2 {
        code: 500,
        msg: "文件夹不存在".to_string(),
    })
}

// 删除本地笔记
#[tauri::command]
async fn remove_note(
    app_handle: tauri::AppHandle,
    current_notebook: String,
    current_note: String,
) -> Result<ResData2, String> {
    let app_dir = app_handle.path_resolver().app_dir();
    if let Some(dir) = app_dir {
        // 本地文件目录
        let local_data_dir = dir.as_path().join("local-data");
        // 文件夹是否存在
        if local_data_dir.exists() {
            let file = local_data_dir
                .join(current_notebook)
                .join(current_note + ".md");
            let remove_res = std::fs::remove_file(file);
            match remove_res {
                Ok(_) => {
                    return Ok(ResData2 {
                        code: 200,
                        msg: "操作成功".to_string(),
                    });
                }
                Err(e) => {
                    return Ok(ResData2 {
                        code: 500,
                        msg: e.to_string(),
                    });
                }
            }
        }
    }
    Ok(ResData2 {
        code: 500,
        msg: "文件夹不存在".to_string(),
    })
}
